/**
 * @author Javier Guaje <jrguajeg@gmail.com>
 */

package co.edu.unal.satacredito.database.dao;

import co.edu.unal.satacredito.database.entity.Franchise;
import co.edu.unal.satacredito.database.exception.NonexistentEntityException;
import co.edu.unal.satacredito.database.exception.UnreachableHostException;
import com.google.code.morphia.Datastore;
import com.google.code.morphia.Key;
import com.google.code.morphia.mapping.Mapper;
import com.google.code.morphia.query.Query;
import com.google.code.morphia.query.UpdateOperations;
import com.google.code.morphia.query.UpdateResults;
import com.mongodb.WriteResult;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bson.types.ObjectId;

public class FranchiseMongoDao {
    
    private static final String TITULAR_FRANCHISE_ID = "_id";
    private static final String FRANCHISE_ID = "franchiseId";
    private static final String FRANCHISE_NAME = "franchiseName";
    private static final String FRANCHISE_TITULAR = "franchiseTitular";
    private static final String USERNAME = "username";
    private static final String PASSWORD = "password";
    private static final String PERMISSION = "permission";
    
    private Datastore mDs;
    
    public FranchiseMongoDao(Datastore ds) {
        this.mDs = ds;
    }
    
    public ObjectId create(Franchise newFranchise) throws UnreachableHostException {
        Key<Franchise> key = mDs.save(newFranchise);
        if (key == null) {
            throw new UnreachableHostException(UnreachableHostException.ERROR_MESSAGE);
        }
        return (ObjectId) key.getId();
    }
    
    public boolean delete(ObjectId id) throws UnreachableHostException {
        try {
            Query<Franchise> query = mDs.find(Franchise.class).field(Mapper.ID_KEY).equal(id);
            Franchise franchise = query.get();
            if (franchise == null) {
                throw new NonexistentEntityException(NonexistentEntityException.ERROR_MESSAGE);
            }
            WriteResult result = mDs.delete(Franchise.class, id);
            if (result == null) {
                throw new UnreachableHostException(UnreachableHostException.ERROR_MESSAGE);
            }
            return true;
        } catch (NonexistentEntityException nee) {
            Logger.getLogger(FranchiseMongoDao.class.getName()).log(Level.SEVERE, null, nee);
            return false;
        }
    }
    
    public boolean update(ObjectId id, Franchise newFranchise) throws UnreachableHostException {
        try {
            Query<Franchise> query = mDs.find(Franchise.class).field(Mapper.ID_KEY).equal(id);
            Franchise franchise = query.get();
            if (franchise == null) {
                throw new NonexistentEntityException(NonexistentEntityException.ERROR_MESSAGE);
            }
            UpdateOperations<Franchise> update = mDs.createUpdateOperations(Franchise.class);
            update.set(FRANCHISE_ID, newFranchise.getFranchiseId());
            update.set(FRANCHISE_NAME, newFranchise.getFranchiseName());
            update.set(FRANCHISE_TITULAR, newFranchise.getFranchiseTitular());
            update.set(USERNAME, newFranchise.getUsername());
            update.set(PASSWORD, newFranchise.getPassword());
            update.set(PERMISSION, newFranchise.getPermission());
            UpdateResults<Franchise> result = mDs.update(query, update);
            if (result == null) {
                throw new UnreachableHostException(UnreachableHostException.ERROR_MESSAGE);
            }
            return true;
        } catch (NonexistentEntityException nee) {
            Logger.getLogger(FranchiseMongoDao.class.getName()).log(Level.SEVERE, null, nee);
            return false;
        }
    }
    
    public Franchise findById(ObjectId id) throws UnreachableHostException {
        return mDs.find(Franchise.class).field(Mapper.ID_KEY).equal(id).get();
    }
    
    public Franchise findByUsernameAndPassword(String username, String password) throws UnreachableHostException {
        Query<Franchise> query = mDs.find(Franchise.class);
        query.field(USERNAME).equal(username);
        query.field(PASSWORD).equal(password);
        return query.get();
    }
    
    public List<Franchise> findAll() {
        Query<Franchise> query = mDs.find(Franchise.class);
        return query.asList();
    }
}